home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
INFO
/
PCCDEMO.ZIP
/
COMP1.EXE
/
MODEX.PRS
< prev
next >
Wrap
Text File
|
1993-12-20
|
30KB
|
485 lines
êìôæÄâöéôêÄì ôÄ îÄâä ù ╧╧╬╠╬╠╬╠╬╠╬╠╡
σΣα≤⌠±Σ α±≤ΦΓδΣ │ Φ φ π Σ ≈
│
│ Ü. αß≥≤±αΓ≤
│ ¢. Φφ≤±επ⌠Γ≤Φεφ ≤ε ≤τΣ ⌡µα
│ αφπ Φ≤≥ £ƒá-Γεδε± ∞επΣ
│ £. µΣ≤≤Φφµ ∞ε±Σ ∩αµΣ≥ αφπ
│ ∩⌠≤≤Φφµ √ε⌠± σΦ±≥≤ ∩Φ≈Σδ
▄██████▄─██████─█████▄─▄█████─██─┐ ██─┐│ ¥. ≤τΣ ±εαπ σ±ε∞ τΣ±Σ
██ ┌█ ┌█ ██ ┌██ ██ ┌██ ██▄▄▄──┘██└██ ┌┘│ ₧. ßεεΩ≥ εφ ≤τΣ ≥⌠ßΘΣΓ≤
██ │█ │█ ██ │██ ██ │██ ██▀▀▀ ▄███▄ │ │ ƒ. ß√Σ - σε± φε÷
██ │█ │█ ██████ █████ ██████─██▀┌▀██└┐│
└─┘└─┘└─┘└─────┘└─────┘└─────┘└─┘ └─┘│
│ σ Φ µ ⌠ ± Σ ≥:
ß√ ±εßΣ±≤ ≥Γτ∞Φπ≤ │ σ¢:
│ memory organization in mode 13h
│
Γ ≥ ε ⌠ ± Γ Σ: ∞επΣ≈δΦß.Γ │ σ£:
v1.1 - simple graphics library │ memory organization in unchained
for planar, 256-color modes - │ modes
optionally self-testing. │
Ü. αß≥≤±αΓ≤ │ understanding of hexadecimal
│ notation and the concepts of
This text gives a fairly │ segments and I/O ports is
basic, yet technical, explanation │ assumed. Keep a VGA reference
to what, why and how Mode X is. │ handy, which at least should have
It first tries to explain the │ definitions of the VGA registers
layout of the VGA memory and the │ at bit level.
shortcomings of the standard │
320x200 256-color mode, then │ Throughout the article, a
gives instructions on how one can │ simple graphics library for
progress from mode 13h to a │ unchained (planar) 256-color
multipage, planar 320x200 256- │ modes is developed. The library
color mode, and from there to the │ supports the 320x200 and 320x240
quasi-standard 320x240 mode, │ modes, active and visible pages,
known as Mode X. │ and writing and reading
│ individual pixels.
A little experience in │
programming the standard VGA mode │
13h (320x200 in 256 colors) is │ ¢. Φφ≤±επ⌠Γ≤Φεφ ≤ε ≤τΣ ⌡µα αφπ
assumed. Likewise a good │ Φ≤≥ £ƒá-Γεδε± ∞επΣ
│ known mode 13h. This mode has
Since its first appearance on │ one good and one bad asset. The
the motherboards of the IBM PS/2 │ good one is that each pixel is
50, 60 and 80 models in 1987, the │ easily addressable in the video
Video Graphics Array has been the │ memory segment at 0A000h. Simply
de facto standard piece of │ calculate the offset using this
graphics hardware for IBM and │ formula:
compatible personal computers. │
The abbreviation, VGA, was to │ offset = (y * 320) + x;
most people synonymous with │
acceptable resolution (640x480 │ Set the byte at this address
pixels), and a stunning rainbow │ (0A000h:offset) to the color you
of colors (256 from a palette of │ want, and the pixel is there.
262,144), at least compared to │ Reading a pixel is just as
the rather gory CGA and EGA │ simple: just read a byte. This
cards. │ was heaven, compared to the hell
│ of planes and masking registers
Sadly, to use 256 colors, the │ needed in 16-color modes.
VGA BIOS limited the users to │ Suddenly, the distance from a
320x200 pixels, i.e. the well- │ graphics algorithm on paper to an
implemented graphics routine was │
cut down to a fraction. The │ Now, the alert reader might
results were impressively fast │ say: "Hold on a minute! If mode
too! │ 13h enables only one page, this
│ means that there is memory for
The bad asset is that mode 13h │ only one page. But I know for a
is also limited to only one page, │ fact that all VGAs have at least
i.e. the VGA can only hold one │ 256 Kb RAM, and one 320x200 256-
screenful at any one time. Most │ color page should consume only
16-color modes let the VGA hold │ 320*200=64000 bytes, which is
more than one page, and this │ less than 64 Kb. A standard VGA
enables you to show one of the │ should room a little more than
pages to the user, while drawing │ four 320x200 pages!" Quite
on another page in the meantime. │ correct, and to see how the BIOS
Page flipping is an important │ puts this limitation on mode 13h,
concept in making flicker free │ I'll elaborate a little on the
animations. Nice looking and │ memory organization of the VGA.
smooth scrolling is also almost │
impossible in this mode using │ The memory is separated into
plain VGA hardware. │ four bit planes. The reason for
this stems from the EGA, where │ since each address in the video
graphics modes were 16-color. │ segment can access 8 pixels, and
Using bit planes, the │ there are 64 Kb addresses, 8 *
designers chose to let each pixel │ 65,536 = 524,288 16-color pixels
on screen be addressable by a │ can be accessed. In a 320x200
single bit in a single byte in │ 16-color mode, this makes for
the video segment. Assuming the │ about 8 (524,288/(320*200))
palette has not been modified │ pages, in 640x480 you get nearly
from the default, each plane │ 2 (524,288/(640*480)) pages.
represent one of the EGA primary │
colors: red, green, blue and │ In a 256-color mode, the
intensity. │ picture changes subtly. The
When modifying the bit │ designers decided to fix the
representing a pixel, the Write │ number of bit planes to 4, so
Plane Enable register is set to │ extending the logic above to 8
the wanted color. Reading is │ planes and 256 colors does not
more complex and slower, since │ work. Instead, one of their
you can only read from a single │ goals was to make the 256-color
plane at a time, by setting the │ mode as easily accessible as
Read Plane Select register. Now, │ possible. Comparing the 8
pixels/address in 16-color modes │ selected bitplane, press F1 for a
to the 1-to-1 correspondence of │ graphical representation.
pixels and addresses of mode 13h, │ Reading works exactly the same
one can say that they have │ way. Since the bit planes are so
succeeded, but at a certain cost. │ closely tied to the address, only
For reasons I am not aware of, │ every fourth byte in the video
the designers came up with the │ memory is accessible, and 192 Kb
following effective, but memory- │ of a 256 Kb VGA go to waste.
wasting scheme: │ Eliminating the need to bother
│ about planes sure is
The address space of mode 13h │ convenientand beneficial, but in
is divided evenly across the four │ most people's opinion the loss of
bit planes. When an 8-bit color │ 3/4 of VGA memory is too much.
value is written to a 16-bit │
address in the VGA segment, a bit │ To accomodate this new method
plane is automatically selected │ of accessing video memory, the
by the 2 least significant bits │ VGA designers introduced a new
of the address. Then all 8 bits │ configuration bit called Chain-4,
of the data is written to the │ which resides as bit number 3 in
byte at the 16-bit address in the │ index 4 of the Sequencer. In 16-
color modes, the default state │ won't bother about these for now.
for this bit is off (zero), and │
the VGA operates as described │ £. µΣ≤≤Φφµ ∞ε±Σ ∩αµΣ≥ αφπ ∩⌠≤≤Φφµ
earlier. In the VGA's standard │ √ε⌠± σΦ±≥≤ ∩Φ≈Σδ
256-color mode, mode 13h, this │
bit is turned on (set to one), │ The observant reader might at
and this turns the tieing of bit │ this time suggest that clearing
planes and memory address on. │ the Chain-4 bit after setting
│ mode 13h will give us access to
In this state, the bit planes │ all 256 Kb of video memory, as
are said to be chained together. │ the two least significant bits of
│ the byte address won't be
Note that Chain-4 in itself is │ `wasted' on selecting a bit
not enough to set a 256-color │ plane. This is correct. You
mode - there are other registers │ might also start feeling a little
which deals with the other subtle │ uneasy, because something tells
changes in nature from 16 to 256 │ you that you'll instantly loose
colors. But, as we now will base │ the simple addressing of mode
our work with mode X on mode 13h, │ 13h. Sadly, that is also
which already is 256-color, we │ correct.
│ is beyond the scope of this
At the moment Chain-4 is │ getting-you-started text, and it
cleared, each byte offset │ wouldn't be very interesting
addresses *four* sequential │ anyway. Here is the minimum
pixels. Before writing to a byte │ snippet of code to initiate the 4
offset in the video segment, you │ page variant of mode 13h, written
should make sure that the 4-bit │ in plain C, using some DOS
mask in the Write Plane Enable │ specific features (see header for
register is set correctly, │ a note about the sources
according to which of the four │ included):
addressable pixels you want to │
modify. In essence, it works │ ----8<-------cut begin------
like a 16-color mode with a │
twist. Press F2 for figure 2. │ /* width and height should
│ specify the mode dimensions.
So, is this mode X? Not │ widthBytes specify the width of a
quite. We need to elaborate to │ line in addressable bytes. */
the VGA how to fetch data for │
refreshing the monitor image. │ int width, height, widthBytes;
Explaining the logic behind this │
/* actStart specifies the start │
of the page being accessed by │ /* Set VGA BIOS mode 13h: */
drawing operations. visStart │
specifies the contents of the │ r.x.ax = 0x0013;
Screen Start register, i.e. the │ int86(0x10, &r, &r);
start of the visible page */ │
│ /* Turn off the Chain-4 bit (bit
unsigned actStart, visStart; │ 3 at index 4, port 0x3c4): */
│
/* │ outport(SEQU_ADDR, 0x0604);
* set320x200x256_X() │
* sets mode 13h, then turns │ /* Turn off word mode, by setting
it into an unchained (planar), 4- │ the Mode Control register of the
page 320x200x256 mode. │ CRT Controller (index 0x17, port
*/ │ 0x3d4): */
│
set320x200x256_X() │ outport(CRTC_ADDR, 0xE317);
{ │
│ /* Turn off doubleword mode, by
union REGS r; │ setting the Underline Location
register (index 0x14, port │
0x3d4): */ │ width = 320;
│ height = 200;
outport(CRTC_ADDR, 0x0014); │
│ /* Each byte addresses four
/* Clear entire video memory, by │ pixels, so the width of a scan
selecting all four planes, then │ line in *bytes* is one fourth of
writing 0 to the entire segment. │ the number of pixels on a line.
*/ │ */
│
outport(SEQU_ADDR, 0x0F02); │ widthBytes = width / 4;
memset(vga+1, 0, 0xffff); │
/* stupid size_t exactly 1 too │ /* By default we want screen
small */ │ refreshing and drawing operations
vga[0] = 0; │ to be based at offset 0 in the
│ video segment. */
/* Update the global variables to │
reflect dimensions of this │ actStart = visStart = 0;
mode. This is needed by most │
future drawing operations. */ │ }
│ graphics operations by the
----8<-------cut end------ │ address of the start of the page,
As you can see, I've already │ as demonstrated in the put pixel
provided some of the mechanics │ routine below. Selecting the
needed to support multiple pages, │ visual page must be passed in to
by providing the actStart and │ the VGA, by setting the Screen
visStart variables. Selecting │ Start register. Sadly enough, the
pages can be done in one of two │ resolution of this register is
contexts: │ limited to one addressable byte,
│ which means four pixels in
1) selecting the visible page, │ unchained 256-color modes. Some
i.e. which page is visible on │ trickery is needed for 1-pixel
screen, and │ smooth, horizontal scrolling, but
│ I'll make that a subject for
2) selecting the active page, │ later.
i.e. which page is accessed by │ The setXXXStart() functions
drawing operations │ provided here accept byte offsets
│ as parameters, so they'll work in
Selecting the active page is │ any mode. If widthBytes and
just a matter of offsetting our │ height are set correctly, so will
the setXXXPage() functions. │ at the top of the screen. This
│ version won't look very well in
----8<-------cut begin------ │ time critical situations (games
│ for instance) as the register
/* │ outputs are not synchronized with
* setActiveStart() tells our │ the screen refresh. This refresh
graphics operations which address │ might start when the high byte is
in video memory should be │ set, but before the low byte is
considered the top left corner. │ set, which produces a bad
*/ │ flicker. */
│
setActiveStart(unsigned offset) │ setVisibleStart(unsigned offset)
{ │ {
actStart = offset; │ visStart = offset;
} │ outport(CRTC_ADDR, 0x0C);
│ /* set high byte */
/* │ outport(CRTC_ADDR+1,
* setVisibleStart() tells the │ visStart >> 8);
VGA from which byte to fetch the │ outport(CRTC_ADDR, 0x0D);
first pixel when starting refresh │ /* set low byte */
outport(CRTC_ADDR+1, │ setVisiblePage(int page)
visStart & 0xff); │ {
} │ setVisibleStart(page * widthBytes
│ * height);
/* │ }
* setXXXPage() sets the │
specified page by multiplying the │ ----8<-------cut end------
page number with the size of one │
page at the current resolution, │ Due to the use of bit planes,
then handing the resulting offset │ the graphics routines tend to get
value over to the corresponding │ more complex than in mode 13h,
setXXXStart() function. The first │ and your first versions will
page number is 0. */ │ generally tend to be a little
│ slower than mode 13h algorithms.
setActivePage(int page) │ Here's a put pixel routine for
{ │ any unchained 256-color mode (it
setActiveStart(page * widthBytes │ assumes that the 'width' variable
* height); │ from the above code is set
} │ correctly). Optimizing is left
│ as an exercise to you, the
reader. This will be the only │
drawing operation I'll cover in │ /* The offset of the pixel into
this article. │ the video segment is offset =
│ (width * y + x) / 4, and write
----8<-------cut begin------ │ the given color to the plane we
│ selected above. Heed the active
putPixel_X(int x, int y, char │ page start selection. */
color) │
{ │ vga[(unsigned)(widthBytes * y) +
│ (x / 4) + actStart] = color;
/* Each address accesses four │
neighboring pixels, so set │ }
Write Plane Enable according to │
which pixel we want to modify. │ char getPixel_X(int x, int y)
The plane is determined by the │ {
two least significant bits of the │
x-coordinate: */ │ /* Select the plane from which we
│ must read the pixel color: */
outportb(0x3c4, 0x02); │
outportb(0x3c5, 0x01 << (x & 3)); │ outport(GRAC_ADDR, 0x04);
outport(GRAC_ADDR+1, x & 3); │ helps quadrupling the speed,
│ especially when drawing
return │ horizontal lines and filling
vga[(unsigned)(widthBytes * y) + │ polygons of a constant color.
(x / 4) + actStart]; │ Also, most block algorithms
│ can be optimized in various ways
} │ so that they need only a constant
│ number of OUTs (typically four)
----8<-------cut end------ │ to the Write Plane Enable
│ register. OUT is a relatively
│ slow instruction.
However, by now you should be │
aware of that the Write Plane │ The gained ability to access
Enable register isn't limited to │ the full 256 Kb of memory on a
selecting just one bit plane, │ standard VGA enables you to do
like the ReadPlane Select │ paging and all the goodies
register is. You can enable any │ following from that: smooth
combination of all four to be │ scrolling over large maps, page
written. This ability to access │ flipping for flicker free
4 pixels with one instruction │ animation... and I'll leave
something for your own │ to when using that phrase.
imagination. │
│ The good thing about the
In short, the stuff gained │ 320x240 mode is that the aspect
from using mode X more than │ ratio is 1:1, which means that
upweighs the additional │ each pixels is 'perfectly'
complexity of using a planar │ square, i.e. not rectangular like
mode. │ in 320x200. An ellipse drawn with
│ the same number of pixels along
Now, the resolution of the │ both main axes will look like a
mode is of little interest in │ perfect circle in 320x240, but
this context. Nearly any 256- │ like a subtly tall ellipse in
color resolution from (about) │ 320x200.
80x8 to 400x300 is available for │
most VGAs. I'll dwell │ Here's a function which sets
particularly by 320x240, as this │ the 320x240 mode. You'll notice
is the mode that Michael Abrash │ that it depends on the first
introduced as 'Mode X' in his DDJ │ piece of code above:
articles. It is also the │
resolution that most people refer │ ----8<-------cut begin------
│ as possible: */
set320x240x256_X() │
{ │ outport(0x3D4, 0x2C11);
│ /* turn off write protect */
/* Set the unchained version of │ outport(0x3D4, 0x0D06);
mode 13h: */ │ /* vertical total */
│ outport(0x3D4, 0x3E07);
set320x200x256_X(); │ /* overflow register */
│ outport(0x3D4, 0xEA10);
/* Modify the vertical sync │ /* vertical retrace start */
polarity bits in the Misc. Output │ outport(0x3D4, 0xAC11);
Register to achieve square aspect │ /* vertical retrace end AND
ratio: */ │ wr.prot */
│ outport(0x3D4, 0xDF12);
outportb(0x3C2, 0xE7); │ /* vertical display enable end */
│ outport(0x3D4, 0xE715);
/* Modify the vertical timing │ /* start vertical blanking */
registers to reflect the │ outport(0x3D4, 0x0616);
increased vertical resolution, │ /* end vertical blanking */
and to center the image as good │
/* Update mode info, so future │ VGA, but this is quite a large
operations are aware of the │ and complex subject, so I'll
resolution: */ │ postpone this to later, if ever.
│
height = 240; │ Anyway, I hope I've helped
│ getting you started using mode X.
} │ As far as I know, the two modes
│ I've used above should work on
----8<-------cut end------ │ *any* VGA and Super VGA
│ available, so this is pretty
As you've figured out, this │ stable stuff. Good luck!
mode will be completely │
compatible with the utility │ ¥. ≤τΣ ±εαπ σ±ε∞ τΣ±Σ
functions presented earlier, │
thanks to the global variable │ I'm providing information on
'height'. │ various libraries and archives
│ which relate to what this article
Other resolutions are achieved │ deals with. If you want me to
through giving other values to │ add anything to this list (for
the sync timing registers of the │ future articles), let me know,
although I can't promise │ graphprg.zip
anything. I am assuming you have │
ftp access. │ Michael Abrash' articles in
│ Doctor Dobbs Journal is always
netcom.com:/pub/profile/game- │ mentioned with awe. In this 350
dev/msdos/xlib04c.zip │ Kb archive, most of his
│ interesting stuff has been
This is the current de facto │ gathered. Read about Mode X
C/assembler library for │ development and techniques from
programming unchained modes (do │ month to month. Included is also
not confuse with a X Windows │ all the individual source code
library). All sources are │ snippets from each article, and
included, and the library is │ also the full XSHARP library
totally free. It has functions │ providing linedrawing, polygons,
for pixels, lines, circles, │ bitmaps, solid 3D projection and
bezier curves, mouse handling, │ speedy rendering, and even an
sprites (bitmaps), compiled │ implementation of 2D texture
bitmaps, and supports a number of │ mapping (can be used for quasi-3D
resolutions. │ texture mapping), plus an article
│ on assembly optimization on the
i86 processor family. Definitely │ might be of interest to the
recommended. │ more adventurous reader. TWEAK
│ lets you play around with the
oak.oakland.edu:/pub/msdos/vga/vg │ registers of the VGA in an
adoc2.zip │ interactive manner. Various
│ testing screens for viewing your
This is a bare bones VGA │ newmade modes are applied at the
register reference. It also │ press of a key. Keep a VGA
contains register references for │ reference handy. Don't try it if
the CGA, EGA and Hercules cards, │ this is the first time you've
in addition to dozens of │ heard of 'registers' or 'mode X'
SuperVGAs. Check out the BOOKS │ or 'tweaking'.
section for some decent VGA │ Watch out for a new version of
references though - you don't │ TWEAK using the familiar Turbo
want to start tweaking without a │ Vision interface, due before
real one. │ Christmas 1993!
│
oak.oakland.edu:/pub/msdos/vga/tw │ ₧. ßεεΩ≥ εφ ≤τΣ ≥⌠ßΘΣΓ≤
eak10.zip │
│ Extremely little has been
published in written form about │ SuperVGAs, which I haven't seen.
using 'Mode X'-style modes. │
Below are some books which cover │ o Michael Abrash : "Power
VGA programming at varying │ Graphics Programming" from
degrees of technical level, but │ QUE/Programmer's Journal.
the only one to mention unchained │ Collections of (old) articles
modes and Mode X, is Michael │ from Programmer's Journal on
Abrash'. I'd get one of the VGA │ EGA/VGA, read modes and write
references first, though. │ modes, animation, tweaking
│ (320x400 and 360x480). His newer
o George Sutty & Steve Blair : │ ravings in DDJ covers fast 256-
"Advanced Pogrammer's Guide to │ color bitmaps, compiled bitmaps,
the EGA/VGA" from Brady. A bit │ polygons, 3D graphics, texture
old perhaps, but covers all │ mapping among other stuff.
*standard* EGA/VGA registers, and │
discusses most BIOS functions and │ o Richard F. Ferraro:
other operations. Contains disk │ "Programmer's Guide to the EGA
with C/Pascal/assembler source │ and VGA video cards including
code. │ Super VGA". I don't have this
There's a sequel out for │ one, but heard it's nice.
Detailed coverage of all EGA/VGA │ resolution you want or need.
registers. The Super VGA │ You will be kept updated via
reference makes it attractive. │ PC COMPLETE. However, I thought
│ I'd let this article go first,
o Richard Wilton : │ and see if I get any reaction. If
"Programmer's Guide to PC & PS/2 │ I don't, I'll stop. So please
Video Systems" Less technical, │ forward any suggestions,
more application/algorithm │ criticisms, bombs and beers. I
oriented. Nice enough, even │ can be contacted via PC COMPLETE.
though it is a bit outdated, in │
that he discusses CGA and │ You may do whatever you like
Hercules cards just as much as │ with the source code supplied in
EGA/VGA. │ LIB.C. Just don't claim it's your
│ work, or make money on it without
ƒ. ß√Σ - σε± φε÷ │ doing some work yourself. Please
│ only distribute ∞επΣ≈δΦß.Γ with
I am considering writing an │ PC COMPLETE ñ
article text describing in more │
detail the process of using │
TWEAK to achieve the VGA │